/*==========================================================================*\
| $Id: Main.java,v 1.1 2009/10/10 17:05:40 aallowat Exp $
|*-------------------------------------------------------------------------*|
| Copyright (C) 2009 Virginia Tech
|
| This file is part of the Web-CAT CxxTest Distribution.
|
| Web-CAT is free software; you can redistribute it and/or modify
| it under the terms of the GNU Affero General Public License as published
| by the Free Software Foundation; either version 3 of the License, or
| (at your option) any later version.
|
| Web-CAT is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU Affero General Public License
| along with Web-CAT; if not, see <http://www.gnu.org/licenses/>.
\*==========================================================================*/
package net.sf.webcat.cxxtest.generator;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
//--------------------------------------------------------------------------
/**
* The main class for the CxxTest generator. Command-line options include:
*
* <dl>
* <dt>-o FILE, --output=FILE</dt>
* <dd>Generates the test runner to FILE; if omitted, output is sent to
* standard output</dd>
* <dt>-l CLASS, --listener=CLASS</dt>
* <dd>The name of the CxxTest listener class that should receive notifications
* about test case events; it is assumed that this class can be included from
* the path <tt><cxxtest/CLASS.h></tt>. This argument can occur multiple
* times to supply multiple listeners that will all receive test notifications
* </dd>
* <dt>-dl LISTENER, --dereferee-listener=LISTENER</dt>
* <dd>The name of the listener module to use with Dereferee (as opposed to a
* CxxTest listener), such as stdio_listener</dd>
* <dt>-dp PLATFORM, --dereferee-platform=PLATFORM</dt>
* <dd>The name of the platform module to use with Dereferee, such as
* gcc_macosx_platform or msvc_win32_platform</dd>
* <dt>--include-dereferee</dt>
* <dd>Include the Dereferee source code along with the CxxTest Root.cpp file.
* Leave this option out if you're linking to a separately compiled Dereferee
* library.</dd>
* <dt>--backtrace</dt>
* <dd>Enables the generation of backtraces upon test case failures; you must
* also supply a value for -dp/--dereferee-platform</dd>
* <dt>--no-trap-signals</dt>
* <dd>Suppresses the use of a signal handler (or under Win32, a structured
* exception handler) that captures segmentation faults and other system
* exceptions and translates them to test case failures. With this option set,
* such exceptions will terminate the application as expected</dd>
* <dt>--long-long=TYPE</dt>
* <dd>The name of the C++ type that should be used to represent a "long long"
* (64-bit) value; if omitted, "long long" will be used</dd>
* </dl>
*
* Following all the options should be the list of C++ header files that
* contain the CxxTest test cases that should be executed.
*
* @author Tony ALlevato
* @version $Id: Main.java,v 1.1 2009/10/10 17:05:40 aallowat Exp $
*/
public class Main
{
//~ Methods ...............................................................
// ----------------------------------------------------------
/**
* The main entry point for the CxxTest generator.
*/
public static void main(String[] args) throws IOException
{
Main main = new Main();
main.run(new ArrayList<String>(Arrays.asList(args)));
}
// ----------------------------------------------------------
private void run(List<String> args)
{
String outputFilename = null;
List<String> listeners = new ArrayList<String>();
List<String> testFiles = new ArrayList<String>();
List<String> additionalDefines = new ArrayList<String>();
boolean trapSignals = true;
boolean backtracing = false;
boolean includeDereferee = false;
String longLongType = null;
String derefereeListener = null;
String derefereePlatform = null;
// Process the command line options.
while (!args.isEmpty())
{
String arg = args.remove(0);
if ("-o".equals(arg))
{
outputFilename = nextArg(args);
}
else if (arg.startsWith("--output"))
{
outputFilename = stripValue(arg);
}
else if ("-l".equals(arg))
{
listeners.add(nextArg(args));
}
else if (arg.startsWith("--listener"))
{
listeners.add(stripValue(arg));
}
else if ("-dl".equals(arg))
{
derefereeListener = nextArg(args);
}
else if (arg.startsWith("--dereferee-listener"))
{
derefereeListener = stripValue(arg);
}
else if ("-dp".equals(arg))
{
derefereePlatform = nextArg(args);
}
else if (arg.startsWith("--dereferee-platform"))
{
derefereePlatform = stripValue(arg);
}
else if ("-d".equals(arg))
{
additionalDefines.add(nextArg(args));
}
else if (arg.startsWith("--define"))
{
additionalDefines.add(stripValue(arg));
}
else if ("--include-dereferee".equals(arg))
{
includeDereferee = true;
}
else if ("--backtrace".equals(arg))
{
backtracing = true;
}
else if ("--no-trap-signals".equals(arg))
{
trapSignals = false;
}
else if (arg.startsWith("--long-long"))
{
longLongType = stripValue(arg);
}
else if (arg.startsWith("-"))
{
System.out.println("Unrecognized option: " + arg);
printUsageAndExit();
}
else
{
testFiles.add(arg);
while (!args.isEmpty())
{
arg = args.remove(0);
testFiles.add(arg);
}
}
}
// Print a usage message if there were any errors in the command line.
if (testFiles.size() == 0)
{
printUsageAndExit();
}
// Collect the test cases from the specified C++ header files and then
// generate the runner source file.
TestSuiteCollector collector = new TestSuiteCollector(testFiles);
TestRunnerGenerator generator = new TestRunnerGenerator(
outputFilename, collector.getSuites(), null, listeners);
generator.setOption("traceStack", backtracing);
generator.setOption("trapSignals", trapSignals);
generator.setOption("longLongType", longLongType);
generator.setOption("includeDereferee", includeDereferee);
generator.setOption("derefereeListener", derefereeListener);
generator.setOption("derefereePlatform", derefereePlatform);
generator.setOption("additionalDefines", additionalDefines);
generator.generate();
}
// ----------------------------------------------------------
private String nextArg(List<String> args)
{
if (args.isEmpty())
{
printUsageAndExit();
return null; // never reached
}
else
{
return args.remove(0);
}
}
// ----------------------------------------------------------
private String stripValue(String arg)
{
int index = arg.indexOf('=');
if (index == -1)
{
printUsageAndExit();
return null; // never reached
}
else
{
return arg.substring(index + 1);
}
}
// ----------------------------------------------------------
private void printUsageAndExit()
{
System.out.println("Usage: cxxtestgen "
+ "[OPTION...] FILES...");
System.out.println("Options:");
System.out.println(
" -o, --output=FILE "
+ "send output to FILE");
System.out.println(
" -l, --listener=NAME "
+ "class name of CxxTest listener");
System.out.println(
" -dl, --dereferee-listener=NAME "
+ "name of Dereferee listener module");
System.out.println(
" -dp, --dereferee-platform=NAME "
+ "name of Dereferee platform module");
System.out.println(
" -d, --define=NAME "
+ "additional preprocessor symbols to define");
System.out.println(
" --backtrace "
+ "enable backtrace collection");
System.out.println(
" --no-trap-signals "
+ "suppress signal trapping logic");
System.out.println(
" --long-long=TYPE "
+ "use TYPE as 'long long'");
System.out.println();
System.exit(1);
}
}